package com.hjx.other;

/**
 * 递归翻转链表
 * 
 * @author houjinxin
 * @version 创建时间：2019/11/1.
 */
public class RecursionReverseList {

    /**
     * 递归版本稍微复杂一些，其关键在于反向工作。假设列表的其余部分已经被反转，现在我该如何反转它前面的部分？假设列表为：n1 → … → nk-1 → nk → nk+1 → … → nm → Ø
     *
     * 若从节点 nk+1 到 nm 已经被反转，而我们正处于 nk。
     *
     * n1 → … → nk-1 → nk → nk+1 ← … ← nm
     *
     * 我们希望 nk+1 的下一个节点指向 nk。
     *
     * 所以，
     *
     * nk.next.next = nk;
     *
     * 要小心的是 n1 的下一个必须指向 Ø 。如果你忽略了这一点，你的链表中可能会产生循环。如果使用大小为 2 的链表测试代码，则可能会捕获此错误。
     * 
     * @param head
     * @return
     */
    public static ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        //暂存当前节点的下一个节点
        ListNode next = head.next;
        ListNode p = reverseList(next);
        //翻转指针
        next.next = head;
        //当前节点的下一节点 置空， 否则 就是 head -> next  next -> head 则会产生死循环
        head.next = null;
        //返回已翻转链表
        return p;
    }

    public static void main(String[] args) {
        ListNode listNode1 = new ListNode(1);
        ListNode listNode2 = listNode1.next = new ListNode(2);
        ListNode listNode3 = listNode2.next = new ListNode(3);
        listNode3.next = new ListNode(4);
//        ListNode listNode1 = null;

        ListNode temp = reverseList(listNode1);
        while (temp != null){
            System.out.println(temp.val);
            temp = temp.next;
        }
    }
}

